Linux基础优化与安全设置

1. 关闭SELinux功能

SELinux(Security-Enhanced Linux)是美国国家安全局(NSA)对于强制访问控制的实现。其实安全问题我们可以通过其它手段来解决,而不用这个SELinux,这也是大多数生产环境的做法,如果非要开启也是可以的。关闭方式如下:

1.1. 修改配置文件,使关闭SELinux永久生效

1
2
3
4
[root@www ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
#<==修改配置文件可使配置永久生效,但必须要重启系统,此步是sed快速修改方法,也可以通过vi编辑修改此文件
[root@www ~]# grep SELINUX=disabled /etc/selinux/config
SELINUX=disabled #<==检查替换结果为disabled就表示成功了

1.2. 临时关闭SELinux

临时关闭SELinux,可在命令行执行如下命令:

1
2
3
4
5
6
7
[root@www ~]# setenforce
usage: setenforce [ Enforcing | Permissive | 1 | 0 ]
#<==数字0表示Permissive,即给出警告提示,但不会阻止操作,相当于disabled
#<==数字1表示Enforcing,即表示SELinux为开启状态
[root@www ~]# setenforce 0 #<==临时将SELinux调成Permissive状态
[root@www ~]# getenforce #<==查看SELinux当前状态
Permissive

命令说明如下:

  • setenforce用于命令行管理SELinux的级别,后面的数字表示设置对应的级别
  • getenforce查看SELinux当前的级别状态
  • 提示:修改配置SELinux后,要想使其生效,必须要重启系统。因此,可配合使用setenforce 0这个临时使其关闭的命令,这样在重启前后都可以使SELinux关闭生效,也就是说必须立刻重启服务器了,在生产场景下Linux机器是不能随意重启的

2. 设定运行级别为3(文本模式)

设定运行级别(runlevel)为3,即表示使用文本命令行模式管理Linux。

1
2
3
4
[root@www ~]# grep 3:initdefault /etc/inittab
id:3:initdefault: #<==这里的3就是Linux默认的运行级别,如有需求可改为其它级别。工作中常用3级别,即文本模式
[root@www ~]# runlevel #<==查看当前系统运行级别
N 3

命令说明:

  • runlevel查看当前系统运行级别
  • init切换运行级别,后面接对应级别的数字,例如init 6是重启Linux服务器

3. 精简开机系统自启动服务

在Linux服务器运行的过程中,会有很多无用的软件服务默认运行,这些服务占用了很多系统资源,而且也带来了安全隐患,因此要关闭。

那么,在企业的生产场景中的Linux主机到底需要保留哪些开机自启动的服务呢?

3.1. 重要的开机自启动服务

在企业环境新装Linux系统之后有必要保留的开机自启动服务有5个,具体如下:

  • sshd远程连接Linux服务器时需要用到这个服务程序,所以必须要开启,否则Linux服务器就无法提供远程连接服务了
  • rsyslog日志相关软件,这是操作系统提供的一种机制,系统的守护程序通常会使用rsyslog程序将各种信息写到各个系统日志文件中,在CentOS6以前此服务的名字为syslog
  • network系统启动时,若想激活或关闭各个网络接口,则必须考虑开启此服务
  • crond该服务用于周期性地执行系统及用户配置的任务计划。有要周期性执行的任务时,就要开启,词服务几乎是生产场景中必须要用的一个软件
  • sysstatsysstat是一个软件包,包含检测系统性能及效率的一组工具,这些工具对于我们收集系统性能数据很有帮助,比如CPU使用率、硬盘和网络吞吐数据等,对这些数据的收集和分析,有利于判断系统运行是否正常,所以它是提高系统运行效率、安全运行服务器的得力助手

sysstat软件包集成的主要工具为:

  • iostat工具提供CPU使用率及硬盘吞吐量效率的数据
  • mpstat工具提供与单个或多个处理器相关的数据
  • sar工具负责收集、报告并存储系统活跃的信息

提示:上面的5个服务是安装完系统后建议保留的开机自启动服务,也几乎是一切生产服务器必须保留的开机自启动服务。将来可根据服务器的业务使用场景调整相应的自启动服务。

3.2. 设置开机自启动服务的常见方法

一:执行命令,然后手动选择处理方法

  1. 方法1:执行ntsysv命令,然后在弹出的窗口中进行设置
  2. 方法2:执行setup命令–>system service,然后在弹出的窗口中进行设置

二:通过一行命令或Shell脚本进行设置

  1. 方法1:先全关闭,再开启需要保留的

    • 操作思路:先将3级别文本模式下默认开启的服务都关闭,然后开启需要开启的服务
    • 操作命令如下:
      1
      2
      3
      4
      # LANG=en
      # for i in `chkconfig --list | grep 3:on | awk '{print $1}'`;do chkconfig --level 3 $i off;done
      # for i in crond network rsyslog sshd sysstat ;do chkconfig --level 3 $i on;done
      # chkconfig --list | grep 3:on
  2. 方法2:一条命令搞定,Shell循环实现

    • 操作思路:默认情况下开机需要保留的服务已经是开启状态了,因此,只需要把3级别文本模式下已经开启但又不需要的服务都关掉就好了
    • 操作过程如下:
      1
      2
      # for i in `chkconfig --list | grep "3:on" | awk '{print $1}' | grep -vE "cond|network|sshd|rsyslog|sysstat"`;do chkconfig $i off;done
      # chkconfig --list | grep 3:on
  3. 方法3:不用Shell循环语句也能一条命令搞定

    • 操作思路:默认情况下开机需要保留的服务都已经是开启状态了,因此,只需要把3级别文本模式下已开启但又不需要开启的服务都关掉就好了,这里将不再用循环结构而是利用命令拼出所有要处理的命令字符串,然后通过bash将其当作命令执行
    • 操作命令如下:

      1
      # chkconfig --list | grep 3:on | grep -vE "crond|sshd|network|rsyslog|sysstat" | awk '{print "chkconfig " $1 " off"}' | bash
    • 1
      # chkconfig --list | grep 3:on | grep -vE "crond|sshd|network|rsyslog|sysstat" | awk '{print $1}' | sed -r 's#(.*)#chkconfig \1 off#g' | bash

提示:到底有哪些服务作为开机自启动服务合适呢?其实这个问题没有唯一的正确答案,主要不影响系统及服务的运行,多开点少开点都是可以的。但是作为一名优秀的Linux系统管理员,我们应该遵守这样一个原则————最小化原则。就是尽量不安装不使用的软件,尽量不开启不需要开启的服务。即只要不用就不开启,这样系统的性能和安全性才是最好的。若随着业务的运行,因安装了软件而需要开机自启动就设置为开机启动即可。一句话,要清除每个服务的角色,不用的绝对不安装,默认安装了的绝对不开机自启动。

4. 关闭iptables防火墙

在企业环境中,一般只有配置外网IP的Linux服务器才需要开启防火墙,但即使有外网IP,高并发、高流量的业务服务器仍然不能开启防火墙,因为开启后会有较大性能损失,导致网站访问速度很慢,这种情况下只能在前端加更好的硬件防火墙了。

关闭防火墙的具体操作过程如下:

1
2
3
4
5
6
7
8
[root@www ~]# /etc/init.d/iptables stop
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]
[root@www ~]# /etc/init.d/iptables stop #<==重复执行确认已关闭
[root@www ~]# chkconfig iptables off #<==关闭开机自启动命令
[root@www ~]# chkconfig --list | grep iptables
iptables 0:off 1:off 2:off 3:off 4:off 5:off 6:off

5. Linux系统安全最小原则说明

最小化原则对Linux系统安全来说及其重要,即多一事不如少一事。具体包括如下几个方面:

  • 安装Linux系统最小化,即选包最小化,yum安装软件包最小化,无用的包不装。
  • 开机自启动服务最小化,即无用的服务不开启。
  • 操作命令最小化。例如:能用rm -f test.txt就不用rm -rf test.txt
  • 登陆Linux用户最小化。平时没有特殊要求不登陆root,用普通用户登陆即可。
  • 普通用户授权权限最小化,即只给用户必须的管理系统的命令。
  • Linux系统文件及目录的权限设置最小化,禁止随意创建、更改、删除文件。

6. 更改SSH服务器端远程登陆的配置

6.1. 更改SSH服务的监听端口

Windows服务器的默认远程管理端口是3389,管理员用户是administrator,普通用户是guest。Linux的管理用户是root,普通用户默认会有很多个,远程连接默认端口是22。

为了系统安全,必须隐藏或更改上述默认配置。更改配置的命令如下:

1
2
3
4
5
6
7
8
9
10
11
# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
#<==更改配置前进行备份,是系统管理员的一个良好的习惯
# vim /etc/ssh/sshd_config #<==编辑ssh_config
### by theshu#2018.04.06###
Port 5233
PermitRootLogin no
PermitEmptyPasswords no
UseDNS no
GSSAPIAuthentication no
### by theshu#2018.04.06###

其中,sshd_config修改的相关参数说明见下表:

参数 说明
Port 指定sshd守护进程监听的端口号,默认为22。默认在本地的所有网络接口上监听,也可以通过ListenAddress指定只在某个特定的接口上监听。
端口范围:0~65535,不能与已有的服务器端口冲突。
一般建议改为比1024大的端口
PermitEmptyPasswords 是否允许密码为空的用户远程登陆。默认为”no”
PermitRootLogin 是否允许root登陆。可用值如下:”yes”(默认)表示允许;”no”表示禁止;
“without-password”表示禁止使用密码认证登陆;
“forced-commands-only”表示只有在指定了command选项的情况下才允许使用公钥认证登陆,同时其它认证方法全部被禁止,这个值常用于做远程备份之类的事情
UseDNS 指定sshd是否应该对远程主机名进行反向解析,以检查此主机名是否与IP地址真实对应。默认为”yes”。
建议改成”no”,否则可能会导致SSH连接很慢
GSSAPIAuthentication 解决Linux之间使用SSH远程连接慢的问题

将以上信息更改后,保存退出。执行如下命令重启sshd,使修改的配置生效:

1
2
3
4
5
[root@www ~]# /etc/init.d/sshd reload
Reloading sshd: [ OK ]
[root@www ~]# /etc/init.d/sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]

提示:reload为平滑重启,不影响正在SSH连接的其它用户,因此要好于restart

此时远程连接Linux,就仅有普通用户可以通过5233端口远程连接到系统中了(本地登陆的用户不受影响)

6.2. 更高级别的SSH安全策略

  1. 更改SSH监听的IP,使其仅监听内网IP。命令如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    vim /etc/ssh/ssh_config
    ###by theshu#2018-04-06##
    Port 5233
    PermitRootLogin no
    PermitEmptyPasswords no
    UseDNS no
    GSSAPIAuthentication no
    ListenAddress 192.168.111.111:5233 #<==就是这一句,企业仅监听本机内网IP地址
    ###by theshu#2018-04-06##
  2. 通过防火墙限制仅能使用内网IP连接此服务器,限制命令如下:

    1
    2
    # 默认规则为DROP时的限制SSH命令
    iptables -I INPUT -p tcp --dport 5233 -s 192.168.111.0/24 -j ACCEPT
  3. 通过拨号到VPN服务器,然后从局域网访问这些服务器,提升安全性。

  4. 工作中的系统安全重点就是互联网TCP/IP连接、对外的Web服务器端口http 80和https 443的安全控制。

7. 利用sudo控制用户对系统命令的使用权限

为了安全及管理的方便,可将需要root权限的普通用户加入sudo管理,这样用户就可以通过自己的普通账户登陆,利用root的权限来管理系统了,当然也就不需要有root账号及密码了。

执行visudo命令,即可打开sudo的配置文件进行编辑:

1
2
# visudo
#<==相当于直接编辑/etc/sudoers,但用命令的方式更安全,推荐使用

在/etc/sudoers文件的大约90几行处,添加需要提升为root权限的普通用户名及对应权限,格式如下:

1
2
root ALL=(ALL) ALL
theshu ALL=(ALL) /usr/sbin/useradd,/usr/sbin/userdel

上述内容不同列对应的说明见表:

用户或组 机器=(授权角色) 可以执行的命令
user MACHINE= COMMANDS
theshu ALL=(ALL) /usr/sbin/useradd,/usr/sbin/userdel

提示:如果theshu用户被授予上述权限,那么它可以在所有的机器上以所有的角色运行useradd和userdel命令。

如果是针对用户组,则对应的授权命令如下:

1
%用户组 机器=(授权使用哪个角色的权限) /usr/sbin/useradd

通过sudo进行授权管理系统的目的:既能让运维人员干活,又不能让其威胁系统安全,其实就是前面讲的用户权限最小化原则,还可以审计用户使用sudo的提权操作命令。

为了管理方便,这里暂时给theshu授权all权限,即可以管理整个系统。配置如下:

1
2
3
root ALL=(ALL) ALL
theshu ALL=(ALL) NOPASSWD: ALL
#<==这个配置结尾的ALL表示theshu可拥有完全的系统管理权限,NOPASSWD表示提权执行命令时不提示密码

配置完成后要进行检查,命令如下:

1
2
# grep theshu /etc/sudoers
theshu ALL=(ALL) NOPASSWD: ALL

也可以使用如下快速操作命令增加sudo授权,仅限于批量管理的情况:

1
2
3
4
5
# \cp /etc/sudoers /etc/sudoers.bak
# echo "theshu ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
# tail -1 /etc/sudoers
# visudo -c #<==直接追加内容没有语法检查,因此要单独执行语法检查命令
/etc/sudoers: parsed OK

说明:

  • 通过sudo授权管理后,所有用户执行授权的特殊权限格式为:sudo 命令
  • 如果需要切换到root执行相关操作,可以通过sudo su -命令,注意,此命令提示的密码为当前用户的密码,而不是root的密码
  • 执行sudo -l命令可以查看当前用户被授予的sudo权限集合,如下:

    1
    2
    3
    [root@www ~]# sudo -l
    User theshu may run the following commands on this host:
    (ALL) NOPASSWD: ALL
  • 对于Linux系统bash的内置命令,一般无法进行sudo授权,例如cd命令。sudo授权对于bash的内置命令的处理,是一个难题,因为内置命令没有实体文件和路径,不过一般都有解决办法。例如可以使用sudo ls替代sudo cd,有的人使用sudo bash后再使用内置命令,这是很危险的,不推荐使用。

在生产环境中,通常会禁止root远程登陆,不过,会为每个运维人员建立一个普通账号,然后根据运维人员的需求,通过sudo控制登陆系统的权限,事实证明这是一个不错的权限管理方式。当然,有些生产环境中还使用了ldap统一认证及授权管理的方式。即只要有一个账号和密码,全公司的多个机房系统内通畅无阻(系统登陆、SVN、VPN等)。
普通用户的环境变量问题:在

8. Linux中文显示设置

此项优化为可选项,即调整Linux系统的字符集设置,那么什么是字符集呢》简单地说,字符集就是一套文字符号和它的编码。目前Linux下常用的字符集有如下几种:

  • GBK:定长,双字节,不是国际标准,支持的系统不少,实际企业用的不多
  • UTF-8:非定常,1~4字节,广泛支持,MySQL也是用UTF-8,企业广泛使用
  • 可通过快捷的命令方式在/etc/sysconfig/i18n中添加如下内容,使其支持中文显示:
    1
    2
    3
    4
    5
    6
    7
    # cat /etc/sysconfig/i18n
    LANG="en_US.UTF-8"
    # cp /etc/sysconfig/i18n /etc/sysconfig/i18n.bak
    # echo ' LANG="zh_CN.UTF-8"' > /etc/sysconfig/i18n
    # source /etc/sysconfig/i18n
    # echo $LANG
    zh_CN.UTF-8

提示:

  • 注意”zh_CN.UTF-8”的大小写字母
  • 这个中文显示配置要与你自己的SSH客户端一致
  • 调整SSH客户端的字符集,使其与Linux服务器端一致(UTF-8)

9. 设置Linux服务器时间同步

Linux系统的时间同步服务为ntp服务。

我们可以手动同步互联网时间到本地Linux主机,命令如下:

1
2
3
4
5
6
[root@www ~]# /usr/sbin/ntpdate time.jmu.edu.cn
9 Apr 12:06:54 ntpdate[1285]: step time server 210.34.128.32 offset 22.581804 sec
#<==如果时间服务器连不上,可以去网上搜索合适的时间服务器
[root@www ~]# which ntpdate
/usr/sbin/ntpdate
#<==注意这个路径,在CentOS5中为/sbin

利用定时任务crond把上述的命令每五分钟自动执行一次,命令如下:

1
2
3
4
5
6
[root@www ~]# echo "#time sync by theshu at 2018-04-09" >> /var/spool/cron/root
[root@www ~]# echo "*/5 * * * * /usr/sbin/ntpdate time.jmu.edu.cn > /dev/null 2>&1" >> /var/spool/cron/root
[root@www ~]# crontab -l
#time sync by theshu at 2018-04-09
*/5 * * * * /usr/sbin/ntpdate time.jmu.edu.cn > /dev/null 2>&1
#<==这个命令其实就是写一个定时任务,相当于执行crontab -e然后加入上面这条内容,保存退出而已

提示:在机器数量少时,可利用以上定时任务进行互联网时间同步,如果机器数量大,那么最好是在内网部署一个时间同步服务器NTP server,然后让自己的网内服务器的时间斗鱼NTP server同步就可以了。

当前,小规模时间同步架构是这样的,即网络内部不搭建时间服务器,所有内部服务都同步外部互联网已有的时间服务器。

大规模集群时间同步架构,内部搭建ntpserver高可用架构,为内部的时间服务器,由这内部的时间服务器与外部时间服务器进行时间同步,然后内部的所有服务器都与内部的时间服务器进行时间同步。

10. 历史记录数及登陆超时环境变量设置

10.1. 设置闲置账号超时时间

设置闲置账号超时时间的示例命令如下,注意此处的配置仅临时生效。

1
2
3
[root@www ~]# export TMOUT=10
[root@www ~]#
timed out waiting for input: suto-logout #<==10秒提示超时

10.2. 设置Linux的命令行历史记录数

设置Linux命令行的历史记录数示例命令如下,注意此处的配置仅临时生效。

1
2
3
4
5
6
[root@www ~]# export HISTSIZE=4
[root@www ~]# history
144 crontab -l
145 crontab -e
146 export HISTSIZE=4
147 history

设定用户的命令行历史记录文件(~/.bash_history)记录指定命令数量的示例命令如下,注意此处的配置仅临时生效。

1
2
3
4
5
6
7
[root@www ~]# export HISTFILESIZE=5
[root@www ~]# cat ~/.bash_history
ifconfig
ping 192.168.111.1
reboot
ping www.qq.com
ifconfig

10.3. 永久配置上述两个内容

把上述命令放入配置文件,使其可以永久生效,命令如下:

1
2
3
4
5
6
7
8
[root@www ~]# echo 'export TMOUT=300' >> /etc/profile
[root@www ~]# echo 'export HISTSIZE=5' >> /etc/profile
[root@www ~]# echo 'export HISTFILESIZE=5' >> /etc/profile
[root@www ~]# tail -3 /etc/profile
export TMOUT=300
export HISTSIZE=5
export HISTFILESIZE=5
[root@www ~]# source /etc/profile

在上述命令中,涉及的系统控制变量说明如下:

  • TMOUT=10连接的超时时间控制变量
  • HISTSIZE=5命令行的历史记录数量变量
  • HISTFILESIZE=10历史记录文件的命令数量变量(~/.bash_history)

提示:实际工作中类似的变量还有不少,到时候可以根据企业的工作需求来选择性使用,最好执行前加上export命令。更多Linux系统的环境变量,可以执行man bash进行查询。

11. 调整Linux系统文件描述符数量

文件描述符是由无符号整数表示的句柄,进程使用它来表示打开的文件。文件描述符与包括相关信息(如文件的打开模式、文件的位置类型、文件的初始类型等)的文件对象相关联,这些信息被称作文件的上下文。文件描述符的有效范围是0到OPEN_MAX。

对于内核而言,所有打开的文件都是通过文件描述符引用的。当打开一个现有文件或创建一个新的文件时,内核想进程返回一个文件描述符。当读或写一个文件时,使用opencreat返回的文件描述符标识该文件,并将其作为参数传递给readwrite,文件描述符定义的内容如下。

1
2
3
4
/* Standard file descriptions. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output */
#define STDERR_FILENO 2 /* Standard error output. */

查看Linux服务器文件描述符设置的情况可以使用ulimit -n命令,文件描述符大小默认是1024。

1
2
[root@www ~]# ulimit -n
1024

对于高并发的业务Linux服务器来说,这个默认的设置值是不够的,需要调整。

11.1. 调整方法1

执行vim /etc/security/limits.conf命令,在文件结尾加上如下一行:

1
* - nofile 65535

或者直接执行如下一行命令追加上述内容到文件尾部:

1
2
3
[root@www ~]# echo '* - nofile 65535' >> /etc/security/limits.conf
[root@www ~]# tail -1 /etc/security/limits.conf
* - nofile 65535

配置完成后,需要重新登陆才可以生效,查看如下:

1
2
[root@www ~]# ulimit -n
65535

11.2. 调整方法2

直接把ulimit -SHn 65535命令加入/etc/rc.local,用以设置每次开机启动时配置生效,命令如下。

1
2
3
4
5
6
7
8
# cat >> /etc/rc.local <<EOF
#-S use the 'soft' resource limit
#-H use the 'hard' resource limit
#-n the maximum number of open file descriptions
ulimit -HSn 65535
#-s the maximum stack size
ulimit -s 65535
EOF

12. Linux服务器内核参数优化

所谓Linux服务器内核参数优化,主要是指在Linux系统中针对业务服务应用而进行系统内核参数调整,优化并无一定标准。下面以生产环境下Linux常见的内核优化为例进行讲解,以供参考。(本优化适合Apache、Nginx、Squid等多种Web应用,特殊的业务有可能需要略作调整。)

优化方法是执行vim /etc/sysctl.conf命令到文件结尾,然后拷贝如下内容并保存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
# 以下参数是针对iptables防火墙的优化,防火墙不会开提示,可以忽略不理
net.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_tcp_timeout_established = 180
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

将上面的内核参数值加入/etc/sysctl.conf文件中,然后执行如下命令使之生效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@www ~]# sysctl -p
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
error: "pv4.tcp_fin_timeout" is an unknown key
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
error: "net.nf_conntrack_max" is an unknown key
error: "net.netfilter.nf_conntrack_max" is an unknown key
error: "net.netfilter.nf_conntrack_tcp_timeout_established" is an unknown key
error: "net.netfilter.nf_conntrack_tcp_timeout_time_wait" is an unknown key
error: "net.netfilter.nf_conntrack_tcp_timeout_close_wait" is an unknown key
error: "net.netfilter.nf_conntrack_tcp_timeout_fin_wait" is an unknown key

如果是在CentOS6环境中,必须开启ip6tables服务才不会出现上面所示的报错,其实报错也可以暂时不利,这是针对防火墙的优化,而此时防火墙是未开启的状态,将来开启了就没问题了。

sysctl.conf内核文件中的参数含义见下表:

参数 说明
net.ipv4.tcp_fin_timeout 表示套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间,默认值是60秒。
该参数对应系统路径为:/proc/sys/net/ipv4/tcp_fin_timeout 60
net.ipv4.tcp_tw_reuse 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认值为0,表示关闭。
该参数对应系统路径为:/proc/sys/net/ipv4/tcp_tw_reuse 0
net.ipv4.tcp_tw_recycle 表示开启TCP链接中TIME-WAIT sockets的快速回收。
该参数对应系统路径为:/proc/sys/net/ipv4/tcp_tw_resycle,默认为0,表示关闭。
提示:reuse和recycle这两个参数是为了防止生产环境下Web、Squid等业务服务器time_wait网络状态数量过多设置的
net.ipv4.tcp_syncookies 表示开启SYN Cookies功能。当出现SYN等待队列溢出时,启用Cookies来处理,可防范少量SYN攻击,CentOS5系列默认值为1,表示开启,因此这个参数也可以不添加。
该参数对应系统路径为:/proc/sys/net/ipv4/tcp_syncookies,默认为1
net.ipv4.tcp_keepalive_time 表示当keepalive启用时,TCP发送keepalive消息的额度。默认是2小时,建议改为10分钟。
该参数对应系统路径为:/proc/sys/net/ipv4/tcp_keepalive_time,默认为7200秒
net.ipv4.ip_local_port_range 该选项用来设定允许系统打开的端口范围,即用于向外连接的端口范围。
该参数对应系统路径为:/prc/sys/net/ipv4/ip_local_port_range 32768 61000
net.ipv4.tcp_max_syn_backlog 表示SYN队列的长度,默认为1024,建议加大列队的长度为8192或更多,这样可以容纳更多等待连接的网络连接数。该参数为服务器端用于记录那些尚未收到客户端确认信息的连接请求最大值。
该参数对应系统路径为:/prc/sys/net/ipv4/tcp_max_syn_backlog
net.ipv4.tcp_max_tw_buckets 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数值,TIE_WAIT套接字将立刻被清除并打印警告信息。默认为180000,对于Apache、Nginx等服务器来说可以将其调低一点,如改为5000~30000,不同业务的服务器也可以给大一点,比如LVS、Squid。
此项参数可以控制TIME-WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
该参数对应系统路径为:/pro/sys/net/ipv4/tcp_max_tw_buckets
net.ipv4.tcp_synack_retries 参数的值决定了内核放弃连接之前发送SYN+ACK包的数量。
该参数对应系统路径为:/proc/sys/net/ipv4/tcp_synack_retries,默认为5
net.ipv4.tcp_syn_retries 表示在内核放弃建立连接之前发送SYN包的数量。
该参数对应系统路径为:/proc/sys/net/ipv4/tcp_syn_retries 5
net.ipv4.tcp_max_orphans 用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数值,鼓励连接将立即被复位比公打印出警告信息。这个限制只是为了防止简单的DoS攻击。不能过分依靠这个限制甚至认为减小这个值,更多的情况是增加这个值。
该参数对应系统路径为:/proc/sys/net/ipv4/tcp_max_orphans 65536
net.core.somaxconn 该选项默认值是128,这个参数用于调节系统同时发起的TCP连接数,在高并发的请求中,默认的值可能会导致链接超时或重传,因此,需要结合并发请求数来调节此值。
该参数对应系统路径为:/proc/sys/net/core/somaxconn 128
net.core.netdev_max_backlog 表示当每个网络接口接收数据包的速率比内核处理这些包的速率块是,允许发送到队列的数据包最大数。
该参数对应系统路径为:/proc/sys/net/core/netdev_max_backlog,默认值为1000

更多网络状态说明及优化命令和优化细节参考其它相关资料。

13. 定时清理邮件服务临时目录垃圾文件

CentOS5系列的系统会默认安装Sendmail服务,因此邮件临时存放地点的路径为/var/spool/clientmqueue/。

CentOS6默认情况下没有安装Sendmail服务,而是改装了Postfix服务,因此邮件临时存放地点的路径为/var/spool/postfix/maildrop/。

以上两个目录很容易被垃圾文件填满,导致系统的inode数量不够用,从而无法存放文件。

手动清理的方法如下:

1
2
3
4
[root@www ~]# find /var/spool/clientmqueue/ -type f | xargs rm -f
#<==适合CentOS5的Sendmail服务
[root@www ~]# find /var/spool/postfix/maildrop/ -type f | xargs rm -f
#<==适合CentOS6的Postfix服务

定时清理的方法为:将上述命令写成脚本,然后做成定时任务,每日凌晨0点执行一次。

下面以CentOS6为例讲解,命令如下:

1
2
3
4
5
6
7
8
9
10
[root@www ~]# mkdir -p /server/scripts
[root@www ~]# echo "find /var/spool/postfix/maildrop/ -type f | xargs rm -f" > /server/scripts/del_file.sh
[root@www ~]# cat /server/scripts/del_file.sh
find /var/spool/postfix/maildrop/ -type f | xargs rm -f
[root@www ~]# echo "#del colentmqueue files by theshu at 2018-04-09" >> /var/spool/cron/root
[root@www ~]# echo "00 00 * * * /bin/bash /server/scripts/del_file.sh > /dev/null 2>&1" >> /var/spool/cron/root
[root@www ~]# crontab -l
#del colentmqueue files by theshu at 2018-04-09
00 00 * * * /bin/bash /server/scripts/del_file.sh > /dev/null 2>&1

14. 隐藏Linux版本信息显示

在登陆到Linux主机本地(非远程连接)前,会显示系统的版本和内核。如下所示:

1
2
3
4
CentOS release 6.9 (Final)
Kernel 2.6.32-696.23.1.e16.x86_64 on an x86_64
www login:

登录后执行如下命令,将产生登陆前终端显示内容的实际存放文件:

1
2
3
4
5
6
7
[root@www ~]# cat /etc/issue
CentOS release 6.9 (Final)
Kernel \r on an \m
[root@www ~]# cat /etc/issue.net
CentOS release 6.9 (Final)
Kernel \r on an \m

执行如下命令清除Linux系统版本及内核信息:

1
2
3
4
[root@www ~]# > /etc/issue
[root@www ~]# cat /etc/issue
[root@www ~]# > /etc/issue.net
[root@www ~]# cat /etc/issue.net

15. 锁定关键系统文件,防止被提权篡改

要锁定关键系统文件,必须对账号密码文件及启动文件枷锁,防止被篡改。上锁命令如下:

1
# chattr +i /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/inittab

提示:上锁后,所有用户都不能对文件修改删除。

解锁的命令如下:

1
# chattr -i /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/inittab

提示:上锁后,如需临时操作,可以解锁后对文件进行修改,之后再上锁。

如果想要更加安全,可以把chattr改名转移,防止被黑客利用。命令如下:

1
2
3
4
5
6
7
8
9
10
11
[root@www ~]# which chattr
/usr/bin/chattr
[root@www ~]# mv /usr/bin/chattr /usr/bin/theshu1
[root@www ~]# chattr -i /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/inittab
-bash: chattr: command not found
[root@www ~]# theshu1 -i /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/inittab
[root@www ~]# lsattr /etc/passwd
-------------e- /etc/passwd
[root@www ~]# theshu1 +i /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/inittab
[root@www ~]# lsattr /etc/passwd
----i--------e- /etc/passwd

提示:chattr有很多参数,例如-a等。如果想要了解更多,请执行man chattr查看。

16. 清除多余的系统虚拟账号

操作前要先根据公司系统提供的服务确定哪些账号不需要使用,如果不确定就不要操作了,一般情况下,一个规范的系统提供的服务都比较少,因此,系统中默认的绝大多数虚拟用户都可以删掉,例如:bin、adm、lp、halt、mail、uucp、oprator、games、gopher、ftp、dbus、vcsa、abrt、ntp、saslauth、postfix、tcpdumo等。这些用户本身也是无法登陆的,因此,词项优化不是必须的。

17. 为grup菜单加密码

为grub菜单加密码的目的是防止他人修改grub进行内核等启动设置,以及用单用户模式启动进行破解root密码等操作。实际上此步可以在安装系统的过程中设定,安装系统后的具体设定步骤如下。

  1. 先利用/sbin/grub-md5-crypt产生一个MD5密码串,命令如下:

    1
    2
    3
    4
    [root@www ~]# /sbin/grub-md5-crypt
    Password:
    Retype password:
    $1$hdyPo/$mndSZIEoiA3EKjTK/t3jA.
  2. 修改grub.conf文件,命令如下:

    1
    2
    3
    4
    5
    6
    7
    8
    ......
    default=0
    timeout=5
    splashimage=(hd0,0)/grub/splash.xpm.gz
    hiddenmenu
    password --md5 $1$hdyPo/$mndSZIEoiA3EKjTK/t3jA.
    title CentOS (2.6.32-696.23.1.el6.x86_64)
    ......

注意:password要加载splashimage和title之间,否则可能无法生效。

设置完成后,下次开机需要管理grub时就会提示输入密码了。

18. 禁止Linux系统被ping

此项优化不是必须的,而且有时我们自己也会通过ping来检查服务器是否异常,对于要求很高的中小企业服务器,设置禁止ping也是可以的。从安全角度来说,禁止ping还是会增加系统安全的。禁止ping的命令如下:

1
2
3
4
[root@www ~]# echo "net.ipv4.icmp_echo_ignore_all=1" >> /etc/sysctl.conf
[root@www ~]# tail -1 /etc/sysctl.conf
net.ipv4.icmp_echo_ignore_all=1
[root@www ~]# sysctl -p

其实这个禁止ping的方法不是最佳策略,因为禁止ping后,我们自己也无法通过ping检查了。还原上述禁止ping的操作,因为工作中用得较少,命令如下:

1
2
3
删除/etc/sysctl.conf中的net.ipv4.icmp_echo_ignore_all=1,保存后,
并执行如下命令:
# echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all

比较好的策略是通过iptables设置让特定的IP可以ping,如让内网用户ping,其它外部用户不能ping。例如:在默认策略为drop的情况下,可以执行如下明林个,使10.0.0.0/24网段允许ping。

1
# iptables -f filter -I INPUT -p icmp --icmp-type 8 -i eth0 -s 10.0.0.0/24 -j ACCEPT

19. 升级具有典型漏洞的软件版本

有时有很多软件在某个版本上会有很多软件漏斗,在企业场景需要对其进行修复。以openssl、openssh、bash等为例,操作步骤如下。

  1. 首先查看相关软件的版本号,命令如下:

    1
    2
    3
    4
    [root@www ~]# rpm -qa openssl openssh bash
    bash-4.1.2-48.el6.x86_64
    openssl-1.0.1e-57.el6.x86_64
    openssh-5.3p1-123.el6_9.x86_64
  2. 升级已知漏洞的软件版本到最新,命令如下:

    1
    2
    3
    [root@www ~]# yum install openssl openssh bash -y
    #<==升级后再查看一下版本信息
    [root@www ~]# rpm -qa openssl openssh bash

20. 总结

Linux基础优化与安全重点小结如下:

  1. 不用root登陆管理系统,而以普通用户身份登陆,通过sudo授权管理。
  2. 更改默认的远程连接SSH服务器端口,禁止root用户远程连接,甚至更改SSH服务只监听内网IP。
  3. 定时自动更新服务器的时间,使其与互联网时间同步。
  4. 配置YUM更新源,从国内更新源下载安装软件包。
  5. 关闭SELinux及iptables(在工作场景中,如果有外部IP一般要打开iptables,高并发、高流量的服务器可能无法开启)。
  6. 调整文件描述符的数量,进程及文件的打开都会消耗文件描述符数量。
  7. 定时自动清理邮件临时目录垃圾文件,防止磁盘的inode数被小文件占满(注意CentOS6与CentOS5要清除的目录不同)。
  8. 精简并保留必要的开机自启动服务(如crond、sshd、network、rsyslog、sysstat)。
  9. Linux内核参数优化/etc/sysctl.conf,执行sysctl -p使其生效。
  10. 更改系统字符集为zh_CN.UTF-8,使其支持中文,防止出现乱码问题。
  11. 锁定关键系统文件,如/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow、/etc/inittab,处理以上内容把chattr、lsattr改名并转移,这样就安全多了。
  12. 清空/etc/issue、/etc/issue.net,去除系统及内核版本登陆前的屏幕显示。
  13. 清除多余的系统虚拟用户账号。
  14. 为grub引导菜单加密码。

提示:上述仅仅为安装Linux后的一些基础优化,更多针对不通过业务服务器的优化思路参考其它相关的资料。

0%